package engineer.view.laravel;

import engineer.view.laravel.editors.ModelEditor;
import fx.FX;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TreeItem;
import javafx.scene.control.TreeView;
import javafx.scene.layout.BorderPane;
import javafx.stage.DirectoryChooser;
import laravel.Laravel;
import laravel.mvc.model.AbstractModel;
import laravel.mvc.model.BaseSubModel;
import laravel.mvc.model.Model;
import laravel.mvc.view.route.Group;
import laravel.mvc.view.route.Route;
import utils.Folder;
import utils.VirtualFolder;

import java.io.File;


/**
 * Created by nuno-rafael-figueiredo on 23-03-2014.
 */
public class LaravelController extends BorderPane {
    @FXML
    private Label pathLabel;

    @FXML
    private Button pathChangeButton;

    @FXML
    private Button completeUserButton;

    @FXML
    private Button writeButton;

    @FXML
    private TreeView treeView;

    @FXML
    private TreeItem<String> baseTreeItem;

    @FXML
    private TreeItem<String> modelsTreeItem;

    @FXML
    private TreeItem<String> routesTreeItem;

    public LaravelController() {
        FX.load(this);
    }

    private Laravel laravel;

    @FXML
    private void initialize() {
        VirtualFolder virtualFolder = Laravel.ROOT_FOLDER;
        Folder folder = virtualFolder.get();
        if (folder != null)
            pathLabel.setText(folder.getName());

        pathChangeButton.setOnAction(event -> selectPath());

        virtualFolder.addListener((observable, oldValue, newValue) -> {
            if (folder != null)
                pathLabel.setText(folder.getName());
        });

        writeButton.setOnAction(e -> write());

        completeUserButton.setOnAction(e ->{
            laravel.completeUser();
            writeButton.setDisable(false);
        });

        treeView.getSelectionModel().selectedItemProperty().addListener((value, before, after) -> onSelect(after));
    }

    private boolean selectPath() {
        File file = new DirectoryChooser()
                .showDialog(getScene().getWindow());

        if (file != null) {
            Laravel.ROOT_FOLDER.set(new Folder(file));
            return true;
        }

        return false;
    }

    private void onSelect(Object o) {
        if (o instanceof ModelTreeItem)
            setCenter(new ModelEditor(((ModelTreeItem) o).getModel()));
        else
            setCenter(null);
    }

    public void write() {
        if (Laravel.ROOT_FOLDER.get() == null){
            if (selectPath())
                laravel.save();
        }
        else
            laravel.save();
    }

    public void setLaravel(Laravel laravel) {
        this.laravel = laravel;

        laravel.setOnFinished(this::work);
    }

    public void work() {
        for (BaseSubModel model : laravel.baseSubModels.values()) {
            final TreeItem<String> treeItem = new ModelTreeItem(model);
            baseTreeItem.getChildren().add(treeItem);
        }

        for (Model model : laravel.models.values()) {
            final TreeItem<String> treeItem = new ModelTreeItem(model);
            modelsTreeItem.getChildren().add(treeItem);
        }

        for (Group group : laravel.getRoutes().getGroups()) {
            final TreeItem<String> treeItem = new TreeItem<>(group.getName());
            routesTreeItem.getChildren().add(treeItem);
            for (Route route : group.getRoutes())
                treeItem.getChildren().add(new TreeItem<>(route.getName()));
        }

        for (Route route : laravel.getRoutes().getRoutes())
            routesTreeItem.getChildren().add(new TreeItem<>(route.getName()));
    }

    @Override
    public String toString() {
        return laravel.toString();
    }

    private class ModelTreeItem extends TreeItem<String> {
        private final AbstractModel model;

        public ModelTreeItem(AbstractModel model) {
            super(model.getName());
            this.model = model;
        }

        public AbstractModel getModel() {
            return model;
        }
    }
}
